package cn.dubnation.base.advice;

import cn.dubnation.base.enums.ResponseCode;
import cn.dubnation.base.exception.BusinessException;
import cn.dubnation.base.exception.FileException;
import cn.dubnation.base.exception.SensitiveInfoException;
import cn.dubnation.base.util.AjaxResult;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import javax.mail.MessagingException;
import java.util.List;
import java.util.Objects;

/**
 * 全局异常处理类
 * @RestControllerAdvice :复合注解@ResponseBbody, @Controller, @ControllerAdvice
 */
@RestControllerAdvice
public class GlobalExceptionHandle {

    /**
     * Controller出现空指针异常会调用该方法
     * @param e
     * @return
     */
    @ExceptionHandler(NullPointerException.class)
    public AjaxResult nullException(NullPointerException e){
        e.printStackTrace();
        return AjaxResult.me().setMessage("空指针异常!")
                              .setCode(ResponseCode.RESPONSE_CODE_400.getCode())
                              .setSuccess(false);
    }

    /**
     * Controller出现任何异常都会调用该方法
     * @param e
     * @return
     */
    @ExceptionHandler(Exception.class)
    public AjaxResult exception(Exception e){
        e.printStackTrace();
        return AjaxResult.me()
                .setCode(ResponseCode.RESPONSE_CODE_400.getCode())
                .setSuccess(false)
                .setMessage("系统异常!");
    }

    /**
     * Controller出现BusinessException业务异常会调用的方法
     * @param e
     * @return
     */
    @ExceptionHandler(BusinessException.class)
    public AjaxResult businessException(BusinessException e) {
        ResponseCode responseCode = e.getResponseCode();
        String message = e.getMessage();
        if (Objects.nonNull(responseCode)){
            return AjaxResult.me().setSuccess(false)
                    .setCode(e.getResponseCode().getCode())
                    .setMessage(e.getResponseCode().getMessage());
        }
        if (Objects.nonNull(message)){
            return AjaxResult.me().setSuccess(false)
                                  .setMessage(e.getMessage())
                                  .setCode(400);
        }
        return null;
    }

    /**
     * 有敏感信息报异常会调用的方法
     * @param e
     * @return
     */
    @ExceptionHandler(SensitiveInfoException.class)
    public AjaxResult sensitiveInfoException(SensitiveInfoException e) {
        return AjaxResult.me().setSuccess(false)
                              .setMessage(e.getMessage())
                              .setCode(e.getCode());
    }

    /**
     * JSR303校验null属性时会调用的方法
     * @param e
     * @return
     */
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public AjaxResult methodArgumentNotValidException(MethodArgumentNotValidException e) {
        List<ObjectError> errors = e.getBindingResult().getAllErrors();
        StringBuffer buffer = new StringBuffer();
        for (int i = 0; i < errors.size(); i++) {
            if (i < errors.size() - 1){
                //最后一位元素之前的所有元素
                buffer.append(errors.get(i).getDefaultMessage()).append(",");
            }else {
                //最后一位元素
                buffer.append(errors.get(i).getDefaultMessage());
            }
        }
        return AjaxResult.me().setSuccess(false)
                              .setCode(ResponseCode.RESPONSE_CODE_400.getCode())
                              .setMessage(buffer.toString());
    }

    /**
     * 发送邮件失败执行的方法
     * @param e
     * @return
     */
    @ExceptionHandler(MessagingException.class)
    public AjaxResult messagingException(MessagingException e) {
        return AjaxResult.me().setSuccess(false)
                              .setCode(500)
                              .setMessage(e.getMessage());
    }
}
